<template>
  <div class="container">
    <baseTable
      :total="usersListTotal"
      :structure="usersListSc"
      :data="usersListData"
      btn-items="export"
      @current-page-change="handleCurrentPageChange"
    >
      <template #operation="{ scope }">
        <el-button style="padding: 5px" type="success" :icon="Edit" text @click="editUser(scope.row.id)">查看详情</el-button>
        <el-button style="padding: 5px" type="danger" :icon="Delete" text @click="deleteUser(scope.row.id)">删除</el-button>
      </template>
    </baseTable>
    <!-- 弹框 -->

    <!-- 个人信息dialog -->
    <BaseDialog v-model:visible="userVisible" @confirm="handleConfirm" title="查看详情">
      <!-- 头像 -->
      <section class="info-image" @click="avatarVisible = true">
        <el-avatar :size="80" :src="avatarUrl" />
        <span class="info-edit">
          <i class="el-icon-lx-camerafill"></i>
        </span>
      </section>
      <!-- 表单 -->
      <el-form :model="userDetailForm" label-position="left" :label-width="80">
        <el-form-item label="邮箱">
          <el-input v-model="userDetailForm.user_email" disabled autocomplete="off" />
        </el-form-item>
        <el-form-item label="昵称">
          <el-input v-model="userDetailForm.user_nickname" autocomplete="off" />
        </el-form-item>
        <el-form-item label="个人简介">
          <el-input v-model="userDetailForm.user_describe" autocomplete="off" />
        </el-form-item>
        <el-form-item label="个人网站">
          <el-input v-model="userDetailForm.website" autocomplete="off" />
        </el-form-item>
        <el-form-item label="创建时间">
          <div>{{ userDetailForm.createAt }}</div>
        </el-form-item>
        <el-form-item label="角色">
          <el-select v-model="userDetailForm.role_id">
            <template v-for="item in roleListData" :key="item.value">
              <el-option :label="item.label" :value="item.value" />
            </template>
          </el-select>
        </el-form-item>
      </el-form>
    </BaseDialog>

    <!-- 更换头像dialog -->
    <BaseDialog v-model:visible="avatarVisible" :width="600">
      <vue-cropper
        ref="cropper"
        :src="avatarUrl"
        :ready="cropImage"
        :zoom="cropImage"
        :cropmove="cropImage"
        style="width: 100%; height: 400px"
      ></vue-cropper>
      <template #footer>
        <span class="dialog-footer">
          <el-button class="crop-demo-btn" type="primary"
            >选择图片
            <input class="crop-input" type="file" name="image" accept="image/*" @change="setImage" />
          </el-button>
          <el-button type="primary" @click="saveAvatar">上传并保存</el-button>
        </span>
      </template>
    </BaseDialog>
  </div>
</template>

<script lang="ts" name="usersList" setup>
  import { onBeforeMount, reactive, ref } from 'vue'
  import { usersListSc } from '@/components/base-table/config'
  import { getUsersListRequest, assignAvatar2UserRequest, deleteUserRequest, updateUserInfoRequest } from '@/network/api/user-api'
  import { queryRoleListRequest } from '@/network/api/rights-api'
  import { UserDetail } from '@/network/api/user-api/types'
  import { Delete, Edit } from '@element-plus/icons-vue'
  import { Irole, Option } from './interface'
  import { ElMessageBox } from 'element-plus'
  import VueCropper from 'vue-cropperjs'
  import 'cropperjs/dist/cropper.css'
  import base64ToFile from '@/utils/base64ToFile'
  import formatUtcTime from '@/utils/formatTime'
  import BaseDialog from '@/components/base-dialog/Index.vue'
  import notification from '@/utils/notification'

  const usersListData = ref<any[]>([])
  const usersListTotal = ref<number>(0)
  const userVisible = ref<boolean>(false) // 详情dialog
  const avatarVisible = ref<boolean>(false) // 头像dialog
  const roleListData = ref<Option[]>([]) // 所有角色
  const userDetailForm = reactive<any>({
    id: 0,
    role_id: 0,
    user_describe: '',
    user_email: '',
    user_nickname: '',
    website: '',
    createAt: '',
  })
  const avatarUrl = ref<string>('')
  const cropper = ref<InstanceType<typeof VueCropper>>() // 图片裁剪ref组件对象
  const cropImg = ref<string>() // 图片裁剪对象

  // 通过canvas画出裁剪的图片
  const cropImage = () => {
    cropImg.value = cropper.value.getCroppedCanvas().toDataURL()
  }

  // 设置裁剪图片
  function setImage(e: any) {
    const file = e.target.files[0]
    if (!file.type.includes('image/')) {
      return
    }
    const reader = new FileReader()
    reader.onload = (event: any) => {
      avatarUrl.value = event.target.result
      cropper.value && cropper.value.replace(event.target.result)
    }
    reader.readAsDataURL(file)
  }

  // 上传头像
  const saveAvatar = async () => {
    const file = base64ToFile(cropImg.value!, Date.now() + '')
    const formData = new FormData()
    formData.append('avatar', file)
    formData.append('userId', userDetailForm.id)
    const result = await assignAvatar2UserRequest(formData)
    const { avatar_url } = result.result
    // 更新界面
    usersListData.value.find(item => item.id === userDetailForm.id).avatar_url = avatar_url + '?' + Math.random()
    notification.success(result.msg)
    avatarVisible.value = false
    // sessionCache.setCache('avatar', avatar_url + '?' + Math.random())
    // userStore.changeAvatar(avatar_url + '?' + Math.random())
  }

  onBeforeMount(async () => {
    await usersListPageInit()
  })

  // 页面初始化：获取用户列表、角色列表
  const usersListPageInit = async (currentPage: number = 1) => {
    // 获取用户列表
    const result = await getUsersListRequest(currentPage)
    const { data, total } = result.result
    usersListData.value = data
    usersListData.value.forEach(item => {
      item.createAt = formatUtcTime(item.createAt)
      item.updateAt = formatUtcTime(item.updateAt)
    })
    usersListTotal.value = total
    // 获取全部角色
    const res = await queryRoleListRequest(1, 100)
    roleListData.value = res.result.data.map((role: Irole) => {
      return { label: role.role_name, value: role.id }
    })
  }

  // 页码改变事件
  const handleCurrentPageChange = async (currentPage: number) => {
    await usersListPageInit(currentPage)
  }

  // 编辑用户: 打开弹窗 初始化表单数据
  const editUser = (id: number) => {
    userVisible.value = true
    const user = usersListData.value.find(item => {
      return item.id === id
    })
    Object.keys(user).forEach(item => {
      userDetailForm[item as keyof UserDetail] = user[item]
    })
    avatarUrl.value = user.avatar_url
  }

  // 删除用户
  const deleteUser = async (id: number) => {
    const reslt = await ElMessageBox.confirm('确定删除吗？', 'Warning', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    }).catch(err => err)
    if (reslt === 'cancel') {
      return notification.info('再想想~')
    } else if (reslt === 'confirm') {
      const result = await deleteUserRequest(id)
      notification.success(result.msg)
      await usersListPageInit()
    }
  }

  // 编辑用户：确定事件
  async function handleConfirm() {
    const result = await updateUserInfoRequest(userDetailForm as UserDetail)
    notification.success(result.msg)
    await usersListPageInit()
    userVisible.value = false
  }
</script>

<style scoped>
  .info-image {
    position: relative;
    margin: auto;
    margin-bottom: 15px;
    width: 80px;
    height: 80px;
    background: #f8f8f8;
    border: 1px solid #eee;
    border-radius: 50px;
    overflow: hidden;
  }
  .info-edit {
    display: flex;
    justify-content: center;
    align-items: center;
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.5);
    opacity: 0;
    transition: opacity 0.3s ease;
  }

  .info-edit i {
    color: #eee;
    font-size: 25px;
  }

  .info-image:hover .info-edit {
    opacity: 1;
  }
  .crop-demo-btn {
    position: relative;
  }

  .crop-input {
    position: absolute;
    width: 100px;
    height: 40px;
    left: 0;
    top: 0;
    opacity: 0;
    cursor: pointer;
  }
</style>
